package com.example.demo.utils;




import com.example.demo.excepiton.UtilException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Sort;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.*;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * spring redis 工具类 *
 * @author xws
 **/
@SuppressWarnings(value = { "unchecked", "rawtypes" })
@Component
public class RedisService
{
    private final Logger log = LoggerFactory.getLogger(RedisService.class);

    @Resource(name = "myRedisTemplate")
    private RedisTemplate redisTemplate;

    @Resource
    private RedisConnectionFactory redisConnectionFactory;

    /**
     *
     * @MethodName：cacheValue
     * @param key
     * @param v
     * @param time(单位秒)  <=0 不过期
     * @return
     * @ReturnType：boolean
     * @Description：缓存value操作
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:24:56
     * @Modifier：
     * @ModifyTime：
     */

    public boolean cacheValue(String key, String v, long time) {
        try {
            ValueOperations<String, String> valueOps =  redisTemplate.opsForValue();
            valueOps.set(key, v);
            if (time > 0){
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("缓存[ {} ]失败, value[ {} ], error[ {} ]",key,v,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }



    /**
     *
     * @MethodName：cacheValue
     * @param key
     * @param v
     * @return
     * @ReturnType：boolean
     * @Description：缓存value操作
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:24:43
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheValue(String key, String v) {
        return cacheValue(key, v, -1);
    }

    /**
     *
     * @MethodName：getValue
     * @param key
     * @return
     * @ReturnType：String
     * @Description：获取缓存
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:21:37
     * @Modifier：
     * @ModifyTime：
     */
    public String getValue(String key) {
        try {
            ValueOperations<String, String> valueOps =  redisTemplate.opsForValue();
            return valueOps.get(key);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ],error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙..");
        }
    }

    /**
     *
     * @MethodName：setExpireTime
     * @param key
     * @return
     * @ReturnType：Boolean
     * @Description：设置缓存时间
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:21:37
     * @Modifier：
     * @ModifyTime：
     */
    public Boolean setExpireTime(String key,long time) {
        try {
            if (time > 0) {
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return false;
        } catch (Exception e) {
            log.error("设置缓存时间失败key[ {} ], time[ {} ],error[ {} ]",key,time,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     * 获取key对应的过期时间, 秒
     * @MethodName：getExpireTime
     * @param key
     * @return
     * @ReturnType：Long
     * @Description：
     * @Creator：yangbiao
     * @CreateTime：2019年7月10日上午9:51:22
     * @Modifier：
     * @ModifyTime：
     */
    public Long getExpireTimeValue(String key){
        try {
            return redisTemplate.getExpire(key);
        }catch (Exception e){
            log.error("获取缓存剩余时间失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：cacheSet
     * @param key
     * @param v
     * @param time
     * @return
     * @ReturnType：boolean
     * @Description：缓存set操作
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:20:00
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheSet(String key, String v, long time) {
        try {
            SetOperations<String, String> valueOps =  redisTemplate.opsForSet();
            valueOps.add(key, v);
            if (time > 0){
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], value[ {} ], error[ {} ]",key,v,e.toString());
            throw new UtilException("服务器繁忙");
        }

    }

    /**
     *
     * @MethodName：cacheSet
     * @param key
     * @param v
     * @return
     * @ReturnType：boolean
     * @Description：缓存set
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:19:00
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheSet(String key, String v) {
        return cacheSet(key, v, -1);
    }

    /**
     *
     * @MethodName：cacheSet
     * @param key
     * @param v
     * @param time
     * @return
     * @ReturnType：boolean
     * @Description：缓存set
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:18:48
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheSet(String key, Set<String> v, long time) {
        try {
            SetOperations<String, String> setOps =  redisTemplate.opsForSet();
            setOps.add(key, v.toArray(new String[v.size()]));
            if (time > 0) {
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], value[ {} ], error[ {} ]",key,v,e.toString());
            throw new UtilException("服务器繁忙");
        }

    }

    /**
     *
     * @MethodName：cacheSet
     * @param key
     * @param v
     * @return
     * @ReturnType：boolean
     * @Description：缓存set
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:18:34
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheSet(String key, Set<String> v) {
        return cacheSet(key, v, -1);
    }

    /**
     *
     * @MethodName：getSet
     * @param key
     * @return
     * @ReturnType：Set<String>
     * @Description：获取缓存set数据
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:17:45
     * @Modifier：
     * @ModifyTime：
     */
    public Set<String> getSet(String key) {
        try {
            SetOperations<String, String> setOps = redisTemplate.opsForSet();
            return setOps.members(key);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：cacheList
     * @param key
     * @param v
     * @param time
     * @return
     * @ReturnType：boolean
     * @Description：list缓存
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:17:23
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheList(String key, String v, long time) {
        try {
            ListOperations<String, String> listOps =  redisTemplate.opsForList();
            listOps.rightPush(key, v);
            if (time > 0) {
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], value[ {} ], error[ {} ]",key,v,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：cacheList
     * @param key
     * @param v
     * @return
     * @ReturnType：boolean
     * @Description：缓存list
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:17:10
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheList(String key, String v) {
        return cacheList(key, v, -1);
    }

    /**
     *
     * @MethodName：cacheList
     * @param key
     * @param v
     * @param time
     * @return
     * @ReturnType：boolean
     * @Description：缓存list
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:15:47
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheList(String key, List<String> v, long time) {
        try {
            ListOperations<String, String> listOps =  redisTemplate.opsForList();
            listOps.rightPushAll(key, v);
            if (time > 0) {
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], value[ {} ], error[ {} ]",key,v,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：cacheList
     * @param key
     * @param v
     * @return
     * @ReturnType：boolean
     * @Description：缓存list
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:15:05
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheList(String key, List<String> v) {
        return cacheList(key, v, -1);
    }

    /**
     *
     * @MethodName：getList
     * @param key
     * @param start
     * @param end
     * @return
     * @ReturnType：List<String>
     * @Description：获取list缓存
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:14:45
     * @Modifier：
     * @ModifyTime：
     */
    public List<String> getList(String key, long start, long end) {
        try {
            ListOperations<String, String> listOps =  redisTemplate.opsForList();
            return listOps.range(key, start, end);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ], start[ {} ], end[ {} ], error[ {} ]",key,start,end,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：getListSize
     * @param key
     * @return
     * @ReturnType：long
     * @Description：获取总条数
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:13:39
     * @Modifier：
     * @ModifyTime：
     */
    public long getListSize(String key) {
        try {
            ListOperations<String, String> listOps =  redisTemplate.opsForList();
            return listOps.size(key);
        } catch (Exception e) {
            log.error("获取长度失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：removeOneOfList
     * @param key
     * @return
     * @ReturnType：boolean
     * @Description：移除list缓存
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:11:16
     * @Modifier：
     * @ModifyTime：
     */
    public boolean removeOneOfList(String key) {
        try {
            ListOperations<String, String> listOps =  redisTemplate.opsForList();
            listOps.rightPop(key);
            return true;
        } catch (Exception e) {
            log.error("移出缓存失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：cacheGeo
     * @param key
     * @param x
     * @param y
     * @param member
     * @param time(单位秒)  <=0 不过期
     * @return
     * @ReturnType：boolean
     * @Description：缓存地理位置信息
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:30:23
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheGeo(String key, double x, double y, String member, long time) {
        try {
            GeoOperations<String, String> geoOps = redisTemplate.opsForGeo();
            geoOps.add(key, new Point(x, y) , member);
            if (time > 0) {
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], x[ {} ], y[ {} ], member[ {} ], time[ {} ], error[ {} ]",key,x,y,member,time,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：cacheGeo
     * @param key
     * @param locations
     * @param time(单位秒)  <=0 不过期
     * @return
     * @ReturnType：boolean
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:31:33
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheGeo(String key, Iterable<RedisGeoCommands.GeoLocation<String>> locations, long time) {
        try {
            for (RedisGeoCommands.GeoLocation<String> location : locations) {
                cacheGeo(key, location.getPoint().getX(), location.getPoint().getY(), location.getName(), time);
            }
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], locations[ {} ], time[ {} ], error[ {} ]",key,locations,time,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：removeGeo
     * @param key
     * @param members
     * @return
     * @ReturnType：boolean
     * @Description：移除地理位置信息
     * @Creator：xws
     * @CreateTime：2019年5月18日上午10:53:01
     * @Modifier：
     * @ModifyTime：
     */
    public boolean removeGeo(String key, String...members) {
        try {
            GeoOperations<String, String> geoOps = redisTemplate.opsForGeo();
            geoOps.remove(key, members);
            return true;
        } catch (Exception e) {
            log.error("移出缓存失败key[ {} ], members[ {} ], error[ {} ]",key,members,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：distanceGeo
     * @param key
     * @param member1
     * @param member2
     * @return Distance
     * @ReturnType：Distance
     * @Description：根据两个成员计算两个成员之间距离
     * @Creator：xws
     * @CreateTime：2019年5月18日上午10:58:33
     * @Modifier：
     * @ModifyTime：
     */
    public Distance distanceGeo(String key, String member1, String member2) {
        try {
            GeoOperations<String, String> geoOps = redisTemplate.opsForGeo();
            return geoOps.distance(key, member1, member2);
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], member1[ {} ], member2[ {} ], error[ {} ]",key,member1,member2,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：getGeo
     * @param key
     * @param members
     * @return
     * @ReturnType：List<Point>
     * @Description：根据key和member获取这些member的坐标信息
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:02:01
     * @Modifier：
     * @ModifyTime：
     */
    public List<Point> getGeo(String key, String...members) {
        try {
            GeoOperations<String, String> geoOps = redisTemplate.opsForGeo();
            return geoOps.position(key, members);
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], members[ {} ], error[ {} ]",key,members,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：radiusGeo
     * @param key
     * @param x
     * @param y
     * @param distance m
     * @return
     * @ReturnType：GeoResults<GeoLocation<String>>
     * @Description：通过给定的坐标和距离(m)获取范围类其它的坐标信息
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:09:10
     * @Modifier：
     * @ModifyTime：
     */
    public GeoResults<RedisGeoCommands.GeoLocation<String>> radiusGeo(String key, double x, double y, double distance, Metric metric, Sort.Direction direction, long limit) {
        try {
            GeoOperations<String, String> geoOps = redisTemplate.opsForGeo();

            //设置geo查询参数
            RedisGeoCommands.GeoRadiusCommandArgs geoRadiusArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
            geoRadiusArgs = geoRadiusArgs.includeCoordinates().includeDistance();//查询返回结果包括距离和坐标
            if (Sort.Direction.ASC.equals(direction)) {//按查询出的坐标距离中心坐标的距离进行排序
                geoRadiusArgs.sortAscending();
            } else if (Sort.Direction.DESC.equals(direction)) {
                geoRadiusArgs.sortDescending();
            }
            geoRadiusArgs.limit(limit);//限制查询数量
            GeoResults<RedisGeoCommands.GeoLocation<String>> radiusGeo = geoOps.radius(key, new Circle(new Point(x, y), new Distance(distance,metric)), geoRadiusArgs);
            return radiusGeo;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], x[ {} ], y[ {} ], distance[ {} ], metric[ {} ], direction[ {} ], limit[ {} ], error[ {} ]",key,x,y,distance,metric,direction,limit,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：containsListKey
     * @param key
     * @return
     * @ReturnType：boolean
     * @Description：判断缓存是否存在
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:23:37
     * @Modifier：
     * @ModifyTime：
     */
    public boolean containsValueKey(String key) {
        return containsKey(key);
    }

    /**
     *
     * @MethodName：containsListKey
     * @param key
     * @return
     * @ReturnType：boolean
     * @Description：判断缓存是否存在
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:23:37
     * @Modifier：
     * @ModifyTime：
     */
    public boolean containsSetKey(String key) {
        return containsKey(key);
    }

    /**
     *
     * @MethodName：containsListKey
     * @param key
     * @return
     * @ReturnType：boolean
     * @Description：判断缓存是否存在
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:23:37
     * @Modifier：
     * @ModifyTime：
     */
    public boolean containsListKey(String key) {
        return containsKey(key);
    }

    /**
     *
     * @MethodName：containsGeoKey
     * @param key
     * @return
     * @ReturnType：boolean
     * @Description：判断缓存是否存在
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:34:14
     * @Modifier：
     * @ModifyTime：
     */
    public boolean containsGeoKey(String key) {
        return containsKey(key);
    }

    public boolean containsKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            log.error("判断缓存存在失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    public boolean containsHashKey(String key,String hashKey) {
        try {
            return redisTemplate.opsForHash().hasKey(key,hashKey);
        } catch (Exception e) {
            log.error("判断缓存存在失败key[ {} ], hashKey[ {} ], error[ {} ]",key,hashKey,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     *
     * @MethodName：remove
     * @param key
     * @return
     * @ReturnType：boolean
     * @Description：移除key中所有缓存
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:20:19
     * @Modifier：
     * @ModifyTime：
     */
    public boolean removeValue(String key) {
        return remove(key);
    }

    /**
     *
     * @MethodName：remove
     * @param key
     * @return
     * @ReturnType：boolean
     * @Description：移除key中所有缓存
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:20:19
     * @Modifier：
     * @ModifyTime：
     */
    public boolean removeSet(String key) {
        return remove(key);
    }

    /**
     *
     * @MethodName：remove
     * @param key
     * @return
     * @ReturnType：boolean
     * @Description：移除key中所有缓存
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:20:19
     * @Modifier：
     * @ModifyTime：
     */
    public boolean removeList(String key) {
        return remove(key);
    }

    /**
     *
     * @MethodName：removeGeo
     * @param key
     * @return
     * @ReturnType：boolean
     * @Description：移除key中所有缓存
     * @Creator：xws
     * @CreateTime：2019年5月18日上午11:36:23
     * @Modifier：
     * @ModifyTime：
     */
    public boolean removeGeo(String key) {
        return remove(key);
    }

    private boolean remove(String key) {
        try {
            return redisTemplate.delete(key);
        } catch (Exception e) {
            log.error("移出缓存失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     * 缓存一个hash键值对到hash表
     * @MethodName：cacheHash
     * @param key
     * @param hashKey
     * @param value
     * @return
     * @ReturnType：boolean
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:43:25
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheHash(String key, String hashKey, Object value){
        try {
            HashOperations<String, String, Object> opsForHash = redisTemplate.opsForHash();
            opsForHash.put(key, hashKey, value);
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], hashKey[ {} ], value[ {} ], error[ {} ]",key,hashKey,value,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }



    /**
     * 缓存一个hash键值对到hash表
     * @MethodName：cacheHash
     * @param key
     * @param hashKey
     * @param value
     * @return
     * @ReturnType：boolean
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:43:25
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheHashStr(String key, String hashKey, String value){
        try {
            HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
            opsForHash.put(key, hashKey, value);
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], hashKey[ {} ], value[ {} ], error[ {} ]",key,hashKey,value,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }


    /**
     * 缓存一个hash键值对到hash表
     * @MethodName：cacheHash
     * @param key
     * @param hashKey
     * @param value
     * @param time
     * @return
     * @ReturnType：boolean
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:43:25
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheHash(String key, String hashKey, Object value, long time){
        try {
            HashOperations<String, String, Object> opsForHash = redisTemplate.opsForHash();
            opsForHash.put(key, hashKey, value);
            if (time > 0){
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], hashKey[ {} ], value[ {} ], time[ {} ], error[ {} ]",key,hashKey,value,time,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     * 缓存一个map到hash表
     * @MethodName：cacheHash
     * @param key
     * @param map
     * @return
     * @ReturnType：boolean
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:45:27
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheHash(String key, Map<String, String> map){
        try {
            HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
            opsForHash.putAll(key, map);
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], value[ {} ], error[ {} ]",key,map,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }
    /**
     * 缓存一个map到hash表
     * @MethodName：cacheHash
     * @param key
     * @param map
     * @param time
     * @return
     * @ReturnType：boolean
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:45:27
     * @Modifier：
     * @ModifyTime：
     */
    public boolean cacheHash(String key, Map<String, String> map, long time){
        try {
            HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
            opsForHash.putAll(key, map);
            if (time > 0) {
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            log.error("缓存失败key[ {} ], value[ {} ], time[ {} ], error[ {} ]",key,map,time,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     * 通过key获取一个map
     * @MethodName：getHash
     * @param key
     * @return
     * @ReturnType：Map<String,String>
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:48:21
     * @Modifier：
     * @ModifyTime：
     */
    public Object getHash(String key,String hashKey){
        try {
            HashOperations<String, String, Object> opsForHash = redisTemplate.opsForHash();
            return opsForHash.get(key,hashKey);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     * 通过key获取一个map
     * @MethodName：getHash
     * @param key
     * @return
     * @ReturnType：Map<String,String>
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:48:21
     * @Modifier：
     * @ModifyTime：
     */

    public String getHashStr(String key,String hashKey){
        try {
            HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
            return opsForHash.get(key,hashKey);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }


    /**
     * 通过key获取一个map
     * @MethodName：getHash
     * @param key
     * @return
     * @ReturnType：Map<String,String>
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:48:21
     * @Modifier：
     * @ModifyTime：
     */
    public long hashLen(String key){
        try {
            HashOperations<String, String, Object> opsForHash = redisTemplate.opsForHash();
            return opsForHash.size(key);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }




    /**
     * 通过key获取一个map
     * @MethodName：getHash
     * @param key
     * @return
     * @ReturnType：Map<String,String>
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:48:21
     * @Modifier：
     * @ModifyTime：
     */
    public long hashHincrBy(String key,String hashKey,long step){
        try {
            HashOperations<String, String, Object> opsForHash = redisTemplate.opsForHash();
            return opsForHash.increment(key,hashKey,step);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ], hashKey[ {} ], step[ {} ], error[ {} ]",key,hashKey,step,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }


    /**
     * 通过key获取一个map
     * @MethodName：getHash
     * @param key
     * @return
     * @ReturnType：Map<String,String>
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:48:21
     * @Modifier：
     * @ModifyTime：
     */
    public Map<String, String> getHash(String key){
        try {
            HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
            return opsForHash.entries(key);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     * 获取key对应map中所有的keys
     * @MethodName：getHashKey
     * @param key
     * @return
     * @ReturnType：Set<String>
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:49:16
     * @Modifier：
     * @ModifyTime：
     */
    public Set<String> getHashKey(String key){
        try {
            HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
            return opsForHash.keys(key);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     * 获取key对应map中所有的values
     * @MethodName：getHashValues
     * @param key
     * @return
     * @ReturnType：List<String>
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:49:55
     * @Modifier：
     * @ModifyTime：
     */
    public List<String> getHashValues(String key){
        try {
            HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
            return opsForHash.values(key);
        } catch (Exception e) {
            log.error("获取缓存失败key[ {} ], error[ {} ]",key,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }

    /**
     * 删除key对应hashMap中key的值.或删除整个key对应map
     * @MethodName：removeHash
     * @param key
     * @param hashKeys
     * @return
     * @ReturnType：List<String>
     * @Description：
     * @Creator：xws
     * @CreateTime：2019年6月27日上午10:51:
     *
     * @Modifier：
     * @ModifyTime：
     */
    public boolean removeHash(String key, String... hashKeys){
        try {
            if (hashKeys == null || hashKeys.length == 0) {
                return redisTemplate.delete(key);
            } else {
                HashOperations<String, String, String> opsForHash = redisTemplate.opsForHash();
                opsForHash.delete(key, hashKeys);
                return true;
            }
        } catch (Exception e) {
            log.error("移出缓存失败key[ {} ], value[ {} ], error[ {} ]",key,hashKeys,e.toString());
            throw new UtilException("服务器繁忙");
        }
    }


    public boolean script(String script,String key,String value){
        try {
            String REPEAT_SCRIPT = script;
            Long result = (Long) redisTemplate.execute(new DefaultRedisScript<Long>(REPEAT_SCRIPT,Long.class), Arrays.asList(key),value);
            if(result == 1){
                return true;
            }
            return false;
        } catch (Exception e) {
            throw new UtilException("服务器繁忙");
        }
    }


    /**
     * 获得缓存的基本对象列表
     *
     * @param pattern 字符串前缀
     * @return 对象列表
     */
    public Collection<String> keys(final String pattern)
    {
        return redisTemplate.keys(pattern);
    }

    /**
     * 删除集合对象
     *
     * @param collection 多个对象
     * @return
     */
    public long removeValue(final Collection collection)
    {
        return redisTemplate.delete(collection);
    }




    @Bean
    public RedisTemplate<String,Object> redisTemplate(){
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
        return redisTemplate;
    }

    /**
     * 设置数据存入 redis 的序列化方式
     *
     * @param redisTemplate
     * @param factory
     */
    private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
        redisTemplate.setConnectionFactory(factory);
    }


    /**
     * 实例化 HashOperations 对象,可以使用 Hash 类型操作
     *
     * @param redisTemplate
     * @return
     */
    @Bean
    public HashOperations<String, String, Object> hashOperations(RedisTemplate<String, Object> redisTemplate) {
        return redisTemplate.opsForHash();
    }





}
